﻿using YiShop.System.Entities;

namespace YiShop.System.Repositories
{
    public class SysDeptRepository : BaseRepository<SysDept, SysDeptDto>
    {
        public SysDeptRepository(ISqlSugarRepository<SysDept> sqlSugarRepository) : base(sqlSugarRepository)
        {
        }

        public override ISugarQueryable<SysDeptDto> DtoQueryable(SysDeptDto dto)
        {
            return Repo.AsQueryable()
                .LeftJoin<SysRoleDept>((d, rd) => d.DeptId == rd.DeptId)
                .Where((d) => d.DelFlag == DelFlag.No)
                .WhereIF(dto.DeptId > 0, (d) => d.DeptId == dto.DeptId)
                .WhereIF(dto.ParentId > 0, (d) => d.ParentId == dto.ParentId)
                .WhereIF(dto.ParentIds!.IsNotEmpty(), (d) => dto.ParentIds!.Contains(d.ParentId))
                .WhereIF(!string.IsNullOrEmpty(dto.DelFlag), (d) => d.DelFlag == dto.DelFlag)
                .WhereIF(!string.IsNullOrEmpty(dto.Status), (d) => d.Status == dto.Status)
                .WhereIF(!string.IsNullOrEmpty(dto.DeptName), (d) => d.DeptName!.Contains(dto.DeptName!))
                .WhereIF(dto.DeptCheckStrictly ?? false, (d) => d.DeptId !=
                    SqlFunc.Subqueryable<SysDept>().InnerJoin<SysRoleDept>((d1, rd1) => d1.DeptId == rd1.DeptId)
                    .Where((d1, rd1) => rd1.RoleId == dto.RoleId)
                    .GroupBy(d1 => d1.ParentId)
                    .Select(d1 => d1.ParentId))
                .Select((d) => new SysDeptDto
                {
                    DeptId = d.DeptId,
                },
                true);
        }

        public override ISugarQueryable<SysDept> Queryable(SysDeptDto dto)
        {
            return Repo.AsQueryable()
                .Where((d) => d.DelFlag == DelFlag.No)
                .WhereIF(dto.DeptId > 0, (d) => d.DeptId == dto.DeptId)
                .WhereIF(dto.ParentId > 0, (d) => d.ParentId == dto.ParentId)
                .WhereIF(!string.IsNullOrEmpty(dto.DelFlag), (d) => d.DelFlag == dto.DelFlag)
                .WhereIF(!string.IsNullOrEmpty(dto.DeptName), (d) => d.DeptName!.Contains(dto.DeptName!))
                .WhereIF(!string.IsNullOrEmpty(dto.Status), (d) => d.Status == dto.Status)
            ;
        }

        // dtos 关联表数据
        protected override async Task FillRelatedDataAsync(IEnumerable<SysDeptDto> dtos)
        {
            if (dtos.IsEmpty()) return;

            // 关联表处理
            var parentIds = dtos.Where(d => d.ParentId.HasValue).Select(d => d.ParentId!.Value).Distinct().ToList();
            var parentDepts = await DtoQueryable(new SysDeptDto { ParentIds = parentIds }).ToListAsync();
            foreach (var dto in dtos)
            {
                dto.ParentName = parentDepts.FirstOrDefault(p => p.DeptId == dto.ParentId)?.DeptName;
            }
        }

        /// <summary>
        /// 是否存在子节点
        /// </summary>
        /// <returns></returns>
        public async Task<bool> HasChildByDeptIdAsync(long parentDeptId)
        {
            var query = new SysDeptDto { DelFlag = DelFlag.No, ParentId = parentDeptId };
            return await AnyAsync(query);
        }
    }
}
